package za.org.meraka.cair.ontorepair;

import org.semanticweb.owlapi.model.*;
import org.protege.editor.owl.ui.clsdescriptioneditor.*;
import org.protege.editor.owl.model.OWLModelManager;

import java.util.Iterator;
import java.util.Set;
import java.util.HashSet;


public class AxiomParser {	
	private OWLExpressionChecker<OWLClassExpression> checker;	
	private OWLDataFactory dataF;	
    private String axiomType;       
    
    static final String	DISJOINT_CLASSES_AXIOM = "DisjointClasses";  
    static final String	EQUIVALENT_CLASSES_AXIOM = "EquivalentClasses";
    static final String	SUBCLASS_AXIOM = "SubClassOf";
    static final String	CLASS_ASSERTION_AXIOM = "Class assertion axiom";
    static final String	OBJECT_PROPERTY_DOMAIN_AXIOM = "Object property domain axiom";
    static final String	OBJECT_PROPERTY_RANGE_AXIOM = "Object property range axiom";
    static final String	SUB_OBJECT_PROPERTY_AXIOM = "Sub object property axiom";
                
	public AxiomParser(OWLModelManager man){
		dataF = man.getOWLDataFactory();	
		checker = man.getOWLExpressionCheckerFactory().getOWLClassExpressionChecker();
	}	
					
	public Set<OWLClassExpression> getOWLClassExpressions(Set<OWLAxiom> axioms) throws OWLException{
		Set<OWLClassExpression> result = new HashSet<OWLClassExpression>();
		
		for (OWLAxiom a: axioms)
			 result.add(getOWLClassExpression(a));			

		return result;
	}
	
	public OWLClassExpression getOWLClassExpression(OWLAxiom ax) throws OWLException{
		axiomType = ax.getAxiomType().toString();
		//System.out.println(axiomType);
		String axiomStr = "";					
			if (axiomType.equals(DISJOINT_CLASSES_AXIOM)){			
				Set<OWLClassExpression> classes = ((OWLDisjointClassesAxiom)ax).getClassExpressions();			
				Iterator<OWLClassExpression> it = classes.iterator();
				OWLClassExpression a = it.next();
				OWLClassExpression b = it.next();				
				Set<OWLClassExpression> aAndB = new HashSet<OWLClassExpression>();
				aAndB.add(a);
				aAndB.add(b);
			
				OWLClassExpression finalDesc = dataF.getOWLObjectIntersectionOf(aAndB);
				return finalDesc;			
			}
			else if (axiomType.equals(EQUIVALENT_CLASSES_AXIOM)){			
				Set<OWLClassExpression> classes = ((OWLEquivalentClassesAxiom)ax).getClassExpressions();			
				Iterator<OWLClassExpression> it = classes.iterator();
				OWLClassExpression a = it.next();
				OWLClassExpression b = it.next();
			
				OWLClassExpression aPrime = dataF.getOWLObjectComplementOf(a);
				OWLClassExpression bPrime = dataF.getOWLObjectComplementOf(b);
			
				Set<OWLClassExpression> aNotB = new HashSet<OWLClassExpression>();
				Set<OWLClassExpression> bNotA = new HashSet<OWLClassExpression>();
				aNotB.add(a);
				aNotB.add(bPrime);
			
				bNotA.add(b);
				bNotA.add(aPrime);
			
				OWLClassExpression aAndNotB = dataF.getOWLObjectIntersectionOf(aNotB);
				OWLClassExpression bAndNotA = dataF.getOWLObjectIntersectionOf(bNotA);
			
				Set<OWLClassExpression> union = new HashSet<OWLClassExpression>();
				union.add(aAndNotB);
				union.add(bAndNotA);
			
				OWLClassExpression finalDesc = dataF.getOWLObjectUnionOf(union); 											
				return finalDesc;
			}
			else if (axiomType.equals(SUBCLASS_AXIOM)){
				OWLSubClassOfAxiom sAx = (OWLSubClassOfAxiom)ax;
				OWLClassExpression subCls = sAx.getSubClass();
				OWLClassExpression superCls = sAx.getSuperClass();
			
				OWLClassExpression notSuperCls = dataF.getOWLObjectComplementOf(superCls);
			
				Set<OWLClassExpression> conj = new HashSet<OWLClassExpression>();
			
				conj.add(subCls);
				conj.add(notSuperCls);
			
				OWLClassExpression aAndNotB = dataF.getOWLObjectIntersectionOf(conj);			
				return aAndNotB;								
			}
			else if (axiomType.equals(CLASS_ASSERTION_AXIOM)){											
				OWLClassExpression desc = checker.createObject(axiomStr);										
				return desc;
			}
			else{			
				return null;
			}		
	}
}
